package com.xg.frame.exception;

import com.xg.frame.entity.ConstantCode;
import com.xg.frame.entity.R;
import com.xg.frame.exception.SqException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.HashMap;

/**
 * 异常通用处理
 * @author dehuisun
 * @version 2017-11-12
 */
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerAdvice {

	/**
	 * 捕获全局以json形式提交的参数异常 @requestBody
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
//	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R controllerException(MethodArgumentNotValidException ex){
		HashMap<String, String> map = new HashMap<>(ex.getBindingResult().getFieldErrors().size());
		ex.getBindingResult().getFieldErrors().forEach(e -> {
			map.put(e.getField(), e.getDefaultMessage());
		});
		log.error("数据校验失败{}",map);
		return R.error().message("数据校验失败，请输入合法数据！").info(map);
	}

	/**
	 * 捕获以表单形式提交的异常
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(BindException.class)
//	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R controllerException(BindException ex){
		HashMap<String, String> map = new HashMap<>(ex.getBindingResult().getFieldErrors().size());
		ex.getBindingResult().getFieldErrors().forEach(e -> {
			map.put(e.getField(), e.getDefaultMessage());
		});
		log.error("数据校验失败{}",map);
		return R.error().message("数据校验失败，请输入合法数据！").info(map);
	}

	/**
	 * 捕获请求参数 @PathVariable and @RequestParam
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(ConstraintViolationException.class)
//	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R controllerException(ConstraintViolationException ex){
		log.error("系统异常", ex);
		return R.error().message("系统请求参数异常").code(ConstantCode.ERROR.getCode());
	}

	/**
	 * 参数校验异常
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
//	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R controllerException(MissingServletRequestParameterException ex){
		log.error("请求参数异常", ex);
		return R.error().message("系统请求参数异常").code(ConstantCode.ERROR.getCode()).info(ex.getMessage());
	}

	@ExceptionHandler({ UnauthorizedException.class })
//	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public R controllerException(UnauthorizedException e) {
		log.error("权限异常", e);
		return R.noAccess().message("无此功能权限");
	}


	/**
	 * 自定义异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler({ SqException.class })
//	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public R controllerException(SqException e) {
		log.error("自定义系统异常", e);
		return R.error().message(e.getMsg()).code(e.getCode());
	}

	/**
	 * 全局异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler({ Exception.class })
//	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public R controllerException(Exception e) {
		log.error("系统异常", e);
		return R.error();
	}



}
